namespace Digitalmes.Domain.Entities.Mes.Productions;

/// <summary>
/// 产品当前实时状态（WIP）。
/// </summary>
[SugarTable("prod_current_state")]
public sealed class ProdCurrentState : EntityBase
{
    /// <summary>
    /// SN
    /// </summary>
    [NotNull]
    public string? Sn { get; set; }

    /// <summary>
    /// 产品 Id。
    /// </summary>
    public long ProductId { get; set; }

    /// <summary>
    /// 产品编码
    /// </summary>
    [NotNull]
    public string? ProductCode { get; set; }

    /// <summary>
    /// 工单编号
    /// </summary>
    public string? Wo { get; set; }

    /// <summary>
    /// 当前所在的生产线 Id
    /// </summary>
    public long LineId { get; set; }

    /// <summary>
    /// 当前所在的工艺路线 Id。
    /// </summary>
    public long RoutingId { get; set; }

    /// <summary>
    /// 当前所在的工序 Id。
    /// </summary>
    public long OperationId { get; set; }

    /// <summary>
    /// 当前所在的工序编号
    /// </summary>
    [NotNull]
    public string? OperationCode { get; set; }

    /// <summary>
    /// 当前所在的工位 Id。
    /// </summary>
    public long WorkstationId { get; set; }

    /// <summary>
    /// 当前所在的工位编号
    /// </summary>
    [NotNull]
    public string? WorkstationCode { get; set; }

    /// <summary>
    /// 产品在当前工位的进站时间
    /// </summary>
    public DateTime InboundTime { get; set; }

    /// <summary>
    /// 产品在当前工位的出站时间
    /// </summary>
    public DateTime? OutboundTime { get; set; }

    /// <summary>
    /// 产品投产上线时间
    /// </summary>
    /// <remarks>根据工艺路线，起始工位进站时间</remarks>
    public DateTime StartedTime { get; set; }

    /// <summary>
    /// 产品完工（或报废）下线时间，未下线则为 null。
    /// </summary>
    /// <remarks>根据工艺路线，末尾工位出站时间，若是 NG 或报废，更加具体情况设置</remarks>
    public DateTime? CompletedTime { get; set; }

    /// <summary>
    /// 产品在当前工位的属处的阶段（进站/出站）。
    /// </summary>
    /// <remarks>
    /// 上件或下件等工位，可能只有出站状态。
    /// </remarks>
    public WorkStageEnum Stage { get; set; }

    /// <summary>
    /// 产品当前作业状态（1->OK，2->NG，3->强制OK，4->强制NG，5->报废）
    /// </summary>
    public PassEnum Status { get; set; } = PassEnum.OK;

    /// <summary>
    /// 是否已完工下线。
    /// </summary>
    /// <remarks>
    /// 若是已在工艺路线中的尾部工位且 OK 下件，即为完工状态；
    /// 或是人为设置为完工状态，如根据条件，返修后不再上线，直接完工。
    /// </remarks>
    public bool IsCompelted { get; set; }

    /// <summary>
    /// 总成码。
    /// </summary>
    /// <remarks>可以记录产品下线时赋予的新条码。</remarks>
    public string? AssemblySn { get; set; }

    /// <summary>
    /// 发生过 NG 次数，包括手动强制 NG。
    /// </summary>
    public int UnfitCount { get; set; }

    /// <summary>
    /// 当前返工单据 Id（不为 0 时表示正处于返工中）。
    /// </summary>
    /// <remarks>
    /// 在线返工，产品正处于的返工单据 Id，在上线过站后清零。
    /// </remarks>
    public long InReworkDocId { get; set; }

    /// <summary>
    /// 产品返工次数。
    /// </summary>
    public int ReworkCount { get; set; }

    /// <summary>
    /// 是否为良品。
    /// </summary>
    /// <returns></returns>
    public bool IsGood() => Status is PassEnum.OK or PassEnum.ForceOK;

    /// <summary>
    /// 是否为不良品（不包含报废）。
    /// </summary>
    /// <returns></returns>
    public bool IsNotGood() => Status is PassEnum.NG or PassEnum.ForceNG;
}
